package com.bird.设计模式.结构型.代理模式.动态代理;

import com.bird.设计模式.结构型.代理模式.Order;
import com.bird.设计模式.结构型.代理模式.db.DataSourceContextHolder;
import com.sun.org.apache.xpath.internal.operations.Or;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @data 2022/3/16 16:21
 * @author: bird
 * @description: 动态代理
 */
public class OrderServiceDynamicProxy implements InvocationHandler {

    // 声明一个目标对象
    private Object target;

    // 通过构造函数 将目标注入进去
    public OrderServiceDynamicProxy(Object target) {
        this.target = target;
    }


    /**
     * @return 获取代理对象
     */
    public Object bind() {
        Class cls = target.getClass();// 目标类的class对象
        // 参数一：目标类的类加载器 参数二：目标类的实现的接口列表 参数三：InvocationHandler
        return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this); // 获取代理对象

    }

    /**
     * 动态代理
     *
     * @param proxy 代理对象
     * @param method 要被增强的对象的方法
     * @param args   方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object argObject = args[0];   // 获取目标对象
         beforeMethod(argObject);    // 在调用目标对象方法之前处理
        Object object = method.invoke(target, args); //调用方法 参数1：目标对象 参数二：目标对象的方法的参数
        afterMethod(); //
        return object;
    }


    /**
     * 动态代理之 增强方法 在目标方法之前进行执行
     *
     * @param obj 目标对象
     *
     */
    private void beforeMethod(Object obj) {
        int userId = 0;
        System.out.println("动态代理：before core!");
        if (obj instanceof Order) {
            Order order = (Order) obj;
            userId = order.getUserId();
        }
        int dbRouter = userId % 2;
        System.out.println("动态代理分配到: db" + dbRouter + " 处理数据");
        DataSourceContextHolder.setDBType("DB" + String.valueOf(dbRouter));
    }


    private void afterMethod() {
        System.out.println("动态代理: after code");
    }

}
